package com.shanxia.codec.cmd;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.enums.DecodeEnum;
import lombok.Data;

import java.util.Arrays;

import static com.shanxia.codec.Decoder.*;

/**
 * S -> C
 * 服务器下发白名单操作日志数据包
 * 后台逐条下发白名单信息报文
 */
@Data
public class Cmd1301 extends ProtocolDataBase {

    public static final int MIN_SIZE = 216; // V3暂时按1字节算

    private int v1;
    private int v2;
    private String sn;                          // 充电桩编码
    private int v3;
    private int operation;                      // 操作
    private int version;                        // 白名单版本号
    private int count;                          // 下发的白名单条数
    private String vin1;                        // 车辆 VIN
    private String vin2;
    private String vin3;
    private String vin4;
    private String vin5;
    private String vin6;
    private String vin7;
    private String vin8;
    private String vin9;
    private String vin10;

    public Cmd1301(){
        super.setCmd(1301);
    }

    public static Cmd1301 decodeFromBase(ProtocolDataBase protocolDataBase) {
        Cmd1301 cmd = new Cmd1301();
        cmd.copyDataFrom(protocolDataBase);
        byte[] dataField = protocolDataBase.getDataField();
        if (dataField.length < MIN_SIZE) {
            cmd.setResult(DecodeEnum.InvalidData);
            return cmd;
        }
        int offset = 0;
        cmd.v1 = getUint16(dataField, offset);
        offset += 2;
        cmd.v2 = getUint16(dataField, offset);
        offset += 2;
        // 32字节充电桩编码
        cmd.sn = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 32), true);
        offset += 32;
        // ？字节（暂时算1字节）预留
        cmd.v3 = getUint8(dataField[offset++]);
        // 1字节操作
        cmd.operation = getUint8(dataField[offset++]);
        // 4字节白名单版本号
        cmd.version = bytesToIntLittle(dataField, offset);
        offset += 4;
        // 4字节下发的白名单条数
        cmd.count = bytesToIntLittle(dataField, offset);
        offset += 4;
        // 17字节车辆VIN
        cmd.vin1 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin2 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin3 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin4 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin5 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin6 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin7 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin8 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin8 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        offset += 17;
        // 17字节车辆VIN
        cmd.vin10 = byteToAscii(Arrays.copyOfRange(dataField, offset, offset + 17), true);
        return cmd;
    }

    @Override
    public byte[] getDataField() {
        byte[] data = new byte[MIN_SIZE];
        int offset = 0;
        getBytesAsUint16(data, offset, this.v1);
        offset += 2;
        getBytesAsUint16(data, offset, this.v2);
        offset += 2;
        // 32字节充电桩编码
        encodeAscii(data, sn, 32, offset);
        offset += 32;
        // 2字节预留
        data[offset++] = (byte) v3;
        // 1字节操作
        data[offset++] = (byte) operation;
        // 4字节白名单版本号
        intToBytesLittle(data, offset, version);
        offset += 4;
        // 4字节下发的白名单条数
        // 4字节白名单版本号
        intToBytesLittle(data, offset, count);
        offset += 4;
        // 17字节车辆VIN
        encodeAscii(data, vin1, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin2, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin3, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin4, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin5, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin6, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin7, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin8, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin9, 17, offset);
        offset += 17;
        // 17字节车辆VIN
        encodeAscii(data, vin10, 17, offset);
        return data;
    }
}
